package com.gzdh.tang.warehouse.rule;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gzdh.tang.comm.constant.SpringContextUtils;
import com.gzdh.tang.comm.handler.IPayRuleHandler;
import com.gzdh.tang.comm.util.ObjectUtil;
import com.gzdh.tang.comm.util.SnowFlake;
import com.gzdh.tang.modu.entity.Fk;
import com.gzdh.tang.modu.entity.Gs;
import com.gzdh.tang.modu.entity.TangDevice;
import com.gzdh.tang.modu.model.CarFoodsModel;
import com.gzdh.tang.modu.model.DeviceCarModel;
import com.gzdh.tang.modu.service.*;
import com.gzdh.tang.modu.vo.InStockTempVo;
import com.gzdh.tang.warehouse.entity.Device;
import com.gzdh.tang.warehouse.service.DeviceService;
import com.gzdh.tang.warehouse.service.InStockService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 仓库小卖部设备消费
 * <p>
 * 支付操作
 */
@Slf4j
public class WarehousePayRule implements IPayRuleHandler {


    FkService fkService;

    GsService gsService;

    MacMainpSbruanService macMainpSbruanService;

    MacMainpSbruanDinnerService macMainpSbruanDinnerService;

    MacMainpSbruanKlService macMainpSbruanKlService;

    ReserveService reserveService;

    TangDeviceService tangDeviceService;

    DeviceService deviceService;

    InStockService inStockService;

    public WarehousePayRule() {
        fkService = (FkService) SpringContextUtils.getBean("fkServiceImpl");
        gsService = (GsService) SpringContextUtils.getBean("gsService");
        macMainpSbruanService = (MacMainpSbruanService) SpringContextUtils.getBean("macMainpSbruanService");
        macMainpSbruanDinnerService = (MacMainpSbruanDinnerService) SpringContextUtils.getBean("macMainpSbruanDinnerService");
        macMainpSbruanKlService = (MacMainpSbruanKlService) SpringContextUtils.getBean("macMainpSbruanKlService");
        reserveService = (ReserveService) SpringContextUtils.getBean("reserveService");
        tangDeviceService = (TangDeviceService) SpringContextUtils.getBean("tangDeviceServiceImpl");
        deviceService = (DeviceService) SpringContextUtils.getBean("deviceServiceImpl");
        inStockService = (InStockService) SpringContextUtils.getBean("inStockService");
    }

    @Override
    @Transactional
    public JSONObject toCardPay(JSONObject params) throws RuntimeException {
        //支付授权码
        String authStr = params.getString("auth");
        log.info("授权码:{}", authStr);
        //获取订单号
        String orders;
        //获取商品
        List<DeviceCarModel> deviceCarModelList = params.getJSONArray("cartModel").toJavaList(DeviceCarModel.class);
        Integer type = params.getInteger("dzkCodeType");

        Fk fk = null;
        String fl = null;
        if (authStr.length() < 10) {
            fk = fkService.getOne(new QueryWrapper<Fk>().lambda().eq(Fk::getCardsn, authStr));
        } else {
            fl = "1";
            switch (type) {
                case 0:
                    throw new RuntimeException("当前模式尚未开通");
                case 1:
                    //通过电子卡解析出来，通过cardNo查询
                    log.info("解码前：" + authStr);
                    byte[] bytes = Base64.getDecoder().decode(authStr);
                    String json = new String(bytes);
                    try {
                        log.info("解码后：" + json);
                        String cardNo = json.split(",")[0].split("=")[1];
                        String dates = json.split(",")[2].split("=")[1];
                        String nowDate = new SimpleDateFormat("yyyyMMddHHmmss")
                                .format(new Date(System.currentTimeMillis() - (2 * (60 * 1000) * 60)));
                        if (new BigDecimal(nowDate).compareTo(new BigDecimal(dates)) > 0) {
                            throw new RuntimeException("二维码已过期");
                        }
                        fk = fkService.getOne(new QueryWrapper<Fk>().lambda().eq(Fk::getCardno, cardNo));
                    } catch (Exception e) {
                        e.printStackTrace();
                        throw new RuntimeException(e.getMessage());
                    }
                    break;
                case 2:
                    //通过数据库读取，获取一次解码
                    fk = fkService.getFkByQr2(authStr);
                    break;
            }
        }
        if (fk == null) {
            throw new RuntimeException("查无此人");
        }
        int sc = 0;
        String date = new SimpleDateFormat("MMdd").format(new Date());
        orders = "XJZF" + date + SnowFlake.nextId();
        int count = gsService.count(new QueryWrapper<Gs>().lambda().eq(Gs::getKh, fk.getKh()).eq(Gs::getCardno, fk.getCardno()));
        if (count > 0 && !"1".equals(fl)) {
            throw new RuntimeException("此卡已挂失");
        }
        deviceCarModelList.get(0).setOrders(orders);
        DeviceCarModel deviceCarModel = deviceCarModelList.get(0);
        if (new BigDecimal(fk.getBtye()).compareTo(deviceCarModel.getAmountPriceSum()) >= 0) {
            sc = 1;
        } else if (new BigDecimal(fk.getKye()).compareTo(deviceCarModel.getAmountPriceSum()) >= 0) {
            sc = 0;
        } else {
            throw new RuntimeException("余额不足");
        }
        //正常状态，可以插入数据库
        depotCardBatch(deviceCarModel, orders, fk.getCardno(), String.valueOf(sc), fl, fk);
        if (sc == 1) {
            BigDecimal btye = new BigDecimal(fk.getBtye()).subtract(deviceCarModel.getAmountPrice());
//            fkService.lambdaUpdate().eq(Fk::getCardno, fk.getCardno())
//                    .set(Fk::getBtye, btye.toPlainString())
//                    .update();
            fk.setBtye(btye.toPlainString());
        } else {
            BigDecimal kye = new BigDecimal(fk.getKye()).subtract(deviceCarModel.getAmountPrice());
//            fkService.lambdaUpdate().eq(Fk::getCardno, fk.getCardno())
//                    .set(Fk::getKye, kye.toPlainString())
//                    .update();
            fk.setKye(kye.toPlainString());
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("fk", fk);
        jsonObject.put("sc", sc);
        jsonObject.put("order", orders);
        return jsonObject;
    }

    @Override
    public JSONObject toCashPay(JSONObject params) throws RuntimeException {
        return null;
    }


    @Override
    public JSONObject toQrPay(JSONObject params) throws RuntimeException {
        return null;
    }

    @Override
    public JSONObject toFacePay(JSONObject params) throws RuntimeException {
        return null;
    }

    private DeviceCarModel depotCardBatch(DeviceCarModel deviceCarModel, String orders, String cardno, String sc, String fl, Fk fk) {
        BigDecimal amountCount = new BigDecimal(0);
        BigDecimal amountPrice = new BigDecimal(0);
        for (CarFoodsModel goo : deviceCarModel.getCarFoods()) {
            amountCount = amountCount.add(new BigDecimal(goo.getFoodNumber()));
            amountPrice = amountPrice.add(new BigDecimal(goo.getFoodNumber()).multiply(new BigDecimal(goo.getPrice())));
        }
        deviceCarModel.setAmountPrice(amountPrice);
        deviceCarModel.setAmountCount(amountCount);
        TangDevice tangDevice = tangDeviceService.getOne(new QueryWrapper<TangDevice>().lambda()
                .eq(TangDevice::getPosnum, deviceCarModel.getOperaId()));
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<InStockTempVo> inStockTempVoList = new ArrayList<>();
        for (CarFoodsModel goo : deviceCarModel.getCarFoods()) {
            Device device = deviceService.getOne(new QueryWrapper<Device>().lambda()
                    .eq(Device::getDeviceid, goo.getBm()));
            InStockTempVo inStockTempVo = new InStockTempVo();
            inStockTempVo.setDeviceid(goo.getBm());
            inStockTempVo.setDevicename(device.getDevicename());
            inStockTempVo.setLogid(deviceCarModel.getOperaId());
            inStockTempVo.setUnit(device.getUnit());
            inStockTempVo.setFlag("CH");
            inStockTempVo.setNumber(inStockTempVo.getNumber());
            inStockTempVo.setLastnumber(ObjectUtil.getBigDecimal(goo.getMaxNumber()));
            inStockTempVo.setPriceVer(goo.getPriceVer());
            inStockTempVo.setPrice(device.getPrice().floatValue());
            inStockTempVo.setSalePrice(new BigDecimal(goo.getPrice()).floatValue());
            inStockTempVo.setNumber(new BigDecimal(goo.getFoodNumber()));
            inStockTempVo.setDh(orders);
            inStockTempVo.setAddr(tangDevice.getAddr());
            inStockTempVo.setCkId(tangDevice.getCkId());
            inStockTempVo.setPihao(orders);
            inStockTempVo.setXddate(simpleDateFormat.format(new Date()));
            inStockTempVo.setCardno(cardno);
            inStockTempVo.setSc(sc);
            inStockTempVo.setInDate(new Date());
            inStockTempVo.setPid(goo.getPid());
            inStockTempVo.setProvider(goo.getProvider());
            inStockTempVo.setPriceAdjustTimes(goo.getPriceAdjustTimes());
            inStockTempVo.setBz(fl);
            InStockTempVo inStockTempVoTemp = new InStockTempVo();
            BeanUtils.copyProperties(inStockTempVo, inStockTempVoTemp);
            inStockTempVoList.add(inStockTempVoTemp);
        }
        inStockService.insertInStock(inStockTempVoList, tangDevice);
        reserveService.depotCardPay(tangDevice, inStockTempVoList, fk, orders, sc, fl);
        return null;
    }


}
